#!/usr/bin/env python3
"""
XCQuant 模拟盘交易启动脚本

启动模拟盘进行网格策略测试
"""

import sys
import os
import time
import signal
import threading
from typing import Dict, Any, Optional

# 添加项目路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from xcquant.core import config_manager, unified_logger
from xcquant.exchanges.okx_adapter import OKXAdapter
from xcquant.trading.order_manager import OrderManager
from xcquant.trading.account_manager import AccountManager
from xcquant.data.data_manager import DataManager
from xcquant.strategies.grid_strategy import GridStrategy
from xcquant.backtesting.mock_exchange import MockExchange
from xcquant.backtesting.mock_managers import MockAccountManager
from xcquant.backtesting.mock_data_manager import MockDataManager


class PaperTradingRunner:
    """模拟盘交易运行器"""
    
    def __init__(self, initial_balance: Dict[str, float]):
        """初始化模拟盘运行器"""
        self.logger = unified_logger.get_logger('paper_trading')
        self.config_manager = ConfigManager()
        
        # 模拟交易所
        self.mock_exchange = MockExchange(initial_balance)
        self.mock_account_manager = MockAccountManager(self.mock_exchange)
        
        # 初始化数据管理器（使用模拟数据管理器）
        data_config = self.config_manager.get_data_config()
        self.data_manager = MockDataManager(data_config)
        
        # 初始化订单管理器
        self.order_manager = OrderManager(self.mock_exchange)
        
        # 策略字典
        self.strategies = {}
        self.running = False
        
        self.logger.info(f"模拟盘交易运行器初始化完成，初始资金: {initial_balance}")
    
    def initialize(self) -> bool:
        """初始化所有组件"""
        try:
            self.logger.info("开始初始化模拟盘交易系统...")
            
            # 不再需要真实交易所，完全使用虚拟数据
            self.logger.info("使用虚拟价格数据，无需连接真实交易所")
            
            # 设置信号处理
            signal.signal(signal.SIGINT, self._signal_handler)
            signal.signal(signal.SIGTERM, self._signal_handler)
            
            self.logger.info("模拟盘交易系统初始化完成")
            return True
            
        except Exception as e:
            self.logger.error(f"系统初始化失败: {e}")
            return False
    
    def create_strategy(self, strategy_config: Dict[str, Any]) -> bool:
        """创建策略"""
        try:
            strategy_name = strategy_config['name']
            
            if strategy_name in self.strategies:
                self.logger.warning(f"策略 {strategy_name} 已存在")
                return False
            
            # 创建网格策略
            strategy = GridStrategy(
                config=strategy_config,
                exchange_adapter=self.mock_exchange,  # 使用模拟交易所
                order_manager=self.order_manager,
                account_manager=self.mock_account_manager,  # 使用模拟账户管理器
                data_manager=self.data_manager
            )
            
            # 初始化策略
            if strategy.initialize():
                self.strategies[strategy_name] = strategy
                self.logger.info(f"策略 {strategy_name} 创建成功")
                return True
            else:
                self.logger.error(f"策略 {strategy_name} 初始化失败")
                return False
                
        except Exception as e:
            self.logger.error(f"创建策略失败: {e}")
            return False
    
    def start_strategy(self, strategy_name: str) -> bool:
        """启动策略"""
        try:
            if strategy_name not in self.strategies:
                self.logger.error(f"策略 {strategy_name} 不存在")
                return False
            
            strategy = self.strategies[strategy_name]
            strategy.start()
            
            self.logger.info(f"策略 {strategy_name} 启动成功")
            return True
            
        except Exception as e:
            self.logger.error(f"启动策略失败: {e}")
            return False
    
    def run(self) -> None:
        """运行模拟盘交易"""
        try:
            self.running = True
            self.logger.info("开始运行模拟盘交易...")
            
            while self.running:
                # 更新市场数据
                self._update_market_data()
                
                # 检查策略状态
                self._check_strategies()
                
                # 显示账户状态
                self._show_account_status()
                
                time.sleep(5)  # 5秒更新一次
                
        except KeyboardInterrupt:
            self.logger.info("收到停止信号，正在关闭...")
        except Exception as e:
            self.logger.error(f"运行时错误: {e}")
        finally:
            self.shutdown()
    
    def _update_market_data(self) -> None:
        """更新市场数据（使用虚拟价格）"""
        try:
            for strategy_name, strategy in self.strategies.items():
                if strategy.is_running():
                    symbol = strategy.symbol
                    
                    # 从模拟数据管理器获取虚拟价格
                    price = self.data_manager.get_latest_price('mock', symbol)
                    if price:
                        # 更新模拟交易所的当前价格
                        self.mock_exchange.set_current_price(symbol, price)
                        
                        # 发送tick数据给策略
                        tick_data = {
                            'symbol': symbol,
                            'price': price,
                            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 统一格式
                        }
                        strategy.on_tick(tick_data)
                        
        except Exception as e:
            self.logger.error(f"更新市场数据失败: {e}")
    
    def _check_strategies(self) -> None:
        """检查策略状态"""
        for strategy_name, strategy in self.strategies.items():
            if strategy.is_running:
                # 检查策略状态
                stats = strategy.get_stats()
                if stats:
                    self.logger.debug(f"策略 {strategy_name} 状态: {stats}")
    
    def _show_account_status(self) -> None:
        """显示账户状态"""
        try:
            balances = self.mock_exchange.balances
            total_value = 0
            
            print("\n" + "="*60)
            print("📊 模拟盘账户状态")
            print("="*60)
            
            for currency, balance in balances.items():
                if balance > 0:
                    if currency == 'USDT':
                        value = balance
                    else:
                        # 获取当前价格计算价值
                        symbol = f"{currency}-USDT"
                        current_price = self.mock_exchange.current_price.get(symbol, 0)
                        value = balance * current_price
                    
                    total_value += value
                    print(f"💰 {currency}: {balance:.6f} (≈ ${value:.2f})")
            
            print(f"\n💎 总资产价值: ${total_value:.2f}")
            
            # 显示策略状态
            print("\n📈 策略状态:")
            for strategy_name, strategy in self.strategies.items():
                if strategy.is_running:
                    stats = strategy.get_stats()
                    print(f"🔄 {strategy_name}: 运行中 | 盈亏: ${stats.get('total_pnl', 0):.2f}")
                else:
                    print(f"⏸️  {strategy_name}: 已停止")
            
            print("="*60)
            
        except Exception as e:
            self.logger.error(f"显示账户状态失败: {e}")
    
    def _signal_handler(self, signum, frame):
        """信号处理器"""
        self.logger.info(f"收到信号 {signum}，正在关闭...")
        self.running = False
    
    def shutdown(self) -> None:
        """关闭系统"""
        try:
            self.logger.info("正在关闭模拟盘交易系统...")
            
            # 停止所有策略
            for strategy_name, strategy in self.strategies.items():
                if strategy.is_running:
                    strategy.stop()
                    self.logger.info(f"策略 {strategy_name} 已停止")
            
            self.running = False
            self.logger.info("模拟盘交易系统已关闭")
            
        except Exception as e:
            self.logger.error(f"关闭系统时出错: {e}")


def main():
    """主函数"""
    try:
        print("🚀 启动XCQuant模拟盘交易系统...")
        
        # 初始资金：1000 USDT
        initial_balance = {'USDT': 1000.0, 'BTC': 0.0, 'ETH': 0.0}
        
        # 创建运行器
        runner = PaperTradingRunner(initial_balance)
        
        # 初始化系统
        if not runner.initialize():
            print("❌ 系统初始化失败")
            return False
        
        # 创建BTC-USDT网格策略
        btc_strategy_config = {
            'name': 'btc_grid',
            'symbol': 'BTC-USDT',
            'exchange': 'okx',
            'type': 'spot',
            'grid_count': 10,
            'single_grid_amount': 50.0,  # 每个网格50 USDT
            'stop_loss_ratio': 0.05,
            'auto_adjust': True
        }
        
        # 创建ETH-USDT网格策略
        eth_strategy_config = {
            'name': 'eth_grid',
            'symbol': 'ETH-USDT',
            'exchange': 'okx',
            'type': 'spot',
            'grid_count': 10,
            'single_grid_amount': 50.0,  # 每个网格50 USDT
            'stop_loss_ratio': 0.05,
            'auto_adjust': True
        }
        
        # 设置虚拟价格（不从真实交易所获取）
        try:
            # 使用虚拟数据生成器获取价格
            from xcquant.data.mock_data_generator import mock_data_generator
            
            btc_ticker = mock_data_generator.generate_ticker_data('BTC-USDT')
            eth_ticker = mock_data_generator.generate_ticker_data('ETH-USDT')
            
            btc_price = float(btc_ticker['price'])
            runner.mock_exchange.set_current_price('BTC-USDT', btc_price)
            print(f"📊 BTC虚拟价格: ${btc_price:.2f}")
            
            eth_price = float(eth_ticker['price'])
            runner.mock_exchange.set_current_price('ETH-USDT', eth_price)
            print(f"📊 ETH虚拟价格: ${eth_price:.2f}")
                
        except Exception as e:
            print(f"⚠️  生成虚拟价格失败，使用默认价格: {e}")
            # 使用默认价格
            runner.mock_exchange.set_current_price('BTC-USDT', 45000.0)
            runner.mock_exchange.set_current_price('ETH-USDT', 3000.0)
        
        # 创建策略
        if not runner.create_strategy(btc_strategy_config):
            print("❌ BTC网格策略创建失败")
            return False
        
        if not runner.create_strategy(eth_strategy_config):
            print("❌ ETH网格策略创建失败")
            return False
        
        # 启动策略
        if not runner.start_strategy('btc_grid'):
            print("❌ BTC网格策略启动失败")
            return False
        
        if not runner.start_strategy('eth_grid'):
            print("❌ ETH网格策略启动失败")
            return False
        
        print("✅ 模拟盘交易系统启动成功")
        print("📊 策略配置:")
        print("   - BTC-USDT 网格策略: 10个网格，每格50 USDT")
        print("   - ETH-USDT 网格策略: 10个网格，每格50 USDT")
        print("   - 初始资金: 1000 USDT")
        print("   - 止损比例: 5%")
        print("\n按 Ctrl+C 停止交易")
        
        # 运行系统
        runner.run()
        
        return True
        
    except Exception as e:
        print(f"❌ 启动失败: {e}")
        return False


if __name__ == "__main__":
    success = main()
    sys.exit(0 if success else 1)